package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.Dto.DishDto;
import com.itheima.reggie.Dto.DishUpdateDto;
import com.itheima.reggie.Dto.QueryListDto;
import com.itheima.reggie.common.CopyFile;
import com.itheima.reggie.common.Result;
import com.itheima.reggie.common.exception.BusinessException;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.invoke.LambdaMetafactory;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Yan
 * @date 2022/2/26
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 添加菜品，同时保存对应的口味数据
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public Result<String> saveWithFlavor(DishDto dishDto) {
        if (ObjectUtils.isEmpty(dishDto)){
            return Result.error("数据有误");
        }
        String name = dishDto.getName();

        BigDecimal price = dishDto.getPrice();
        if (ObjectUtils.isEmpty(name)||ObjectUtils.isEmpty(price)){
            return Result.error("数据有误");
        }
        //保存菜品的基本信息到菜品表
//        Dish dish =new Dish();
        ModelMapper mm = new ModelMapper();
        Dish dish = mm.map(dishDto, Dish.class);


        this.save(dish);

        try {
            CopyFile.copy(dish.getImage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("文件复制失败");
        }


        //菜品id
        Long dishId = dish.getId();

        List<DishFlavor> flavors = dishDto.getFlavors();
        //从Dto的flavors中取出dishId，存到一个新的集合中
        List<DishFlavor> collect = flavors.stream().peek(dishFlavor -> dishFlavor.setDishId(dishId)).collect(Collectors.toList());

        dishFlavorService.saveBatch(collect);

        return Result.success("添加成功");
    }

    @Override
    public Result<Page<QueryListDto>> findDishPage(Long page, Long pageSize, String name) {
        if (ObjectUtils.isEmpty(page)||page<=0){
            page=1L;
        }
        if (ObjectUtils.isEmpty(pageSize)||pageSize<=0){
            pageSize=10L;
        }

        Page<Dish> pageParam = new Page<>(page,pageSize);

        LambdaQueryWrapper<Dish> wrapper =new LambdaQueryWrapper<>();
        wrapper.like(!ObjectUtils.isEmpty(name),Dish::getName,name);
        wrapper.orderByDesc(Dish::getUpdateTime);
        Page<Dish> result =this.page(pageParam,wrapper);

        List<Dish> records = result.getRecords();

        //创建一个返回集合
        List<QueryListDto> listDtos = new ArrayList<>();

        for (Dish record : records) {
            Long categoryId = record.getCategoryId();
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            QueryListDto queryListDto =new QueryListDto();
            BeanUtils.copyProperties(record,queryListDto);

            queryListDto.setCategoryName(categoryName);

            listDtos.add(queryListDto);

        }

        //返回数据
        Page<QueryListDto> targetResult = new Page<>();
        BeanUtils.copyProperties(result,targetResult);
        targetResult.setRecords(listDtos);

        return Result.success(targetResult);
    }

    @Override
    public Result<DishUpdateDto> findDishById(Long id) {
        //1.参数校验
        if(ObjectUtils.isEmpty(id)){
            return Result.error("数据错误");
        }
        //2.执行逻辑
        //2.1获取菜品数据
        Dish dish = this.getById(id);
        //2.2获取口味数据
        LambdaQueryWrapper<DishFlavor> wrapper =new LambdaQueryWrapper<>();
        //根据菜品id查询口味
        wrapper.eq(DishFlavor::getDishId,id);
        List<DishFlavor> flavorList = dishFlavorService.list(wrapper);

        DishUpdateDto dishUpdateDto =new DishUpdateDto();
        BeanUtils.copyProperties(dish,dishUpdateDto);

        dishUpdateDto.setFlavors(flavorList);
        return Result.success(dishUpdateDto);
    }

    @Override
    @Transactional
    public Result<String> updateDish(DishUpdateDto dishUpdateDto) {
        if (ObjectUtils.isEmpty(dishUpdateDto)){
            return Result.error("数据错误");
        }

        //更新dish数据
        Dish dish =new Dish();
        BeanUtils.copyProperties(dishUpdateDto,dish);
        this.saveOrUpdate(dish);

        //更新口味：先删除，再插入
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(DishFlavor::getDishId,dish.getId());
        dishFlavorService.remove(wrapper);

        //添加
        List<DishFlavor> flavors = dishUpdateDto.getFlavors();

        flavors = flavors.stream().map(dishFlavor -> {
            dishFlavor.setDishId(dish.getId());
            return dishFlavor;
        }).collect(Collectors.toList());

        /*for (DishFlavor flavor : flavors) {
            flavor.setDishId(dish.getId());
        }*/

        dishFlavorService.saveBatch(flavors);

        return Result.success("更新成功");

    }

    @Override
    public Result<List<DishDto>> listByCategoryId(Long categoryId,Integer status) {
        if (ObjectUtils.isEmpty(categoryId)){
            return Result.error("数据错误");
        }

        LambdaQueryWrapper<Dish> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(Dish::getCategoryId,categoryId);
        //查询起售（status==1）的菜品
        wrapper.eq(ObjectUtils.isNotEmpty(status),Dish::getStatus,status);
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        List<Dish> list = this.list(wrapper);

        List<DishDto> dishDtos =list.stream().map(dish -> {
            DishDto dishDto =new DishDto();
            BeanUtils.copyProperties(dish,dishDto);
            //添加分类名称
            Long categoryId1 = dish.getCategoryId();
            Category category = categoryService.getById(categoryId1);

            if (ObjectUtils.isNotEmpty(category)){
                dishDto.setCategoryName(category.getName());
            }

            //添加风味列表
            LambdaQueryWrapper<DishFlavor> wrapper1 =new LambdaQueryWrapper<>();
            wrapper1.eq(DishFlavor::getDishId,dish.getId());
            List<DishFlavor> dishFlavors = dishFlavorService.list(wrapper1);

            dishDto.setFlavors(dishFlavors);
            return dishDto;
        }).collect(Collectors.toList());

        return Result.success(dishDtos);
    }

    @Override
    @Transactional
    public Result<String> deleteDishByList(List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)){
            return Result.error("数据不对");
        }

        //套餐中有的不能删，
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper =new LambdaQueryWrapper<>();
        setmealDishWrapper.in(SetmealDish::getDishId,ids);
        List<SetmealDish> setmealDishList = setmealDishService.list(setmealDishWrapper);

        List<Long> collect = setmealDishList.stream().map(SetmealDish::getDishId).collect(Collectors.toList());

        ids.removeAll(collect);

        if (ids.size()==0){
            return Result.error("菜品删除失败");
        }


        // 在启售的不能删
        LambdaQueryWrapper<Dish> wrapper =new LambdaQueryWrapper<>();

        wrapper.in(Dish::getId,ids);

        List<Dish> list = this.list(wrapper);
        List<Long> delIds = new ArrayList<>();
        for (Dish dish : list) {
            if (dish.getStatus()==0){
                //停售的菜品放入删除集合中
                delIds.add(dish.getId());
            }
        }

        if (ObjectUtils.isEmpty(delIds)){
            return Result.error("菜品在启售删除失败");
        }


        //删除菜品风味表里数据
        LambdaQueryWrapper<DishFlavor> dishFlavorWrapper =new LambdaQueryWrapper<>();
        dishFlavorWrapper.in(DishFlavor::getDishId,delIds);
        dishFlavorService.remove(dishFlavorWrapper);

        //删除菜品表
        this.removeByIds(delIds);

        return Result.success("删除停售菜品成功");
    }

    /**
     * 菜品起售停售
     * @param status
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public Result<String> dishStatus(Integer status, List<Long> ids) {
        if (ObjectUtils.isEmpty(status)||ObjectUtils.isEmpty(ids)){
            return Result.error("数据不对噢");
        }

        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getDishId,ids);
        List<SetmealDish> setmealDishlist = setmealDishService.list(wrapper);

        List<Long> collect = setmealDishlist.stream().map(SetmealDish::getDishId).collect(Collectors.toList());

        ids.removeAll(collect);
        if (ids.size()==0){
            return Result.error("修改失败");
        }


        if (setmealDishlist.size()!=0){
            return Result.error("菜品在套餐里，停售不了");
        }


        List<Dish> list = this.listByIds(ids);
        for (Dish dish : list) {
            dish.setStatus(status);
        }

        this.saveOrUpdateBatch(list);

        if (status==0){
            return Result.success("停售成功");
        }
        return Result.success("起售成功");
    }










    /*public Result<String> addDish(DishDto dishDto){
        if (ObjectUtils.isEmpty(dishDto)){
            return Result.error("数据有误");
        }

        Dish dish =new Dish();
        //把对象中同名的值，赋值给目标对象
        BeanUtils.copyProperties(dishDto,dish);
        this.save(dish);

        //往口味表里添加口味
        List<DishFlavor> flavors =dishDto.getFlavors();
        flavors=flavors.stream().map((flavor)->{
            flavor.setDishId(dish.getId());
            return flavor;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);
        return Result.success("添加数据");
    }*/
}
